import { Inject, Provide } from "@midwayjs/core";
import { InjectEntityModel } from "@midwayjs/typeorm";
import { Repository } from "typeorm";
import { Utils } from "../utils";
import { BblCase } from "../entity/case.entity";
import { BblAttach } from "../entity/attach.entity";
import { AttachService } from "./att.service";
import {
  CaseCreateDto,
  CaseDto,
  CasePageQueryDto,
  CaseUpdateDto
} from "../dto/case.dto";

@Provide()
export class CaseService {
  @Inject()
  utils: Utils;

  @Inject()
  attService: AttachService;

  /**
   * 附件驱动模型
   */
  @InjectEntityModel(BblCase)
  model: Repository<BblCase>;

  async get_origin(caseId: string) {
    const builder = this.model
      .createQueryBuilder("case")
      .leftJoinAndSelect("case.caseCoverImg", "caseCoverImg")
      .leftJoinAndSelect("case.caseMainImgs", "caseMainImgs")
      .where("case.caseId = :caseId", { caseId });

    return await builder.getOne();
  }

  async add_case(dto: CaseCreateDto) {
    const bcase = new BblCase();

    bcase.caseId = this.utils.uuid();
    bcase.caseMainTitle = dto.caseMainTitle;
    bcase.caseSubTitle = dto.caseSubTitle;
    bcase.caseText = dto.caseText;

    const caseCoverImg = new BblAttach();
    caseCoverImg.attId = dto.caseCoverAttId;
    bcase.caseCoverImg = caseCoverImg;

    bcase.caseMainImgs = dto.caseMainAttIds.map((d) => {
      const att = new BblAttach();
      att.attId = d;
      return att;
    });

    const result = await this.model.save(bcase);

    const origin = await this.get_origin(result.caseId);
    const files: BblAttach[] = [];
    files.push(origin.caseCoverImg);
    files.push(...origin.caseMainImgs);
    await this.attService.tmp_to_uploads(files);

    return this.utils.service.success(result.caseId);
  }

  async update_case(caseId: string, dto: CaseUpdateDto) {
    let bcase = await this.get_origin(caseId);
    if (!bcase) {
      return this.utils.service.fail("案例不存在");
    }

    bcase.caseMainTitle = dto.caseMainTitle;
    bcase.caseSubTitle = dto.caseSubTitle;
    bcase.caseText = dto.caseText;

    const rfiles = [];
    // 封面图片id不一致,删除原来的图片
    if (
      !bcase.caseCoverImg ||
      bcase.caseCoverImg.attId !== dto.caseCoverAttId
    ) {
      bcase.caseCoverImg && rfiles.push(bcase.caseCoverImg);
      const caseCoverImg = new BblAttach();
      caseCoverImg.attId = dto.caseCoverAttId;
      bcase.caseCoverImg = caseCoverImg;
    }

    bcase.caseMainImgs.forEach((d) => {
      if (!dto.caseMainAttIds.includes(d.attId)) {
        rfiles.push(d);
      }
    });

    bcase.caseMainImgs = dto.caseMainAttIds.map((d) => {
      const att = new BblAttach();
      att.attId = d;
      return att;
    });
    this.attService.remove(rfiles);
    await this.model.save(bcase);

    bcase = await this.get_origin(caseId);

    await this.attService.tmp_to_uploads([
      bcase.caseCoverImg,
      ...bcase.caseMainImgs
    ]);

    return this.utils.service.success(bcase);
  }

  async delete_case(caseId: string) {
    const bcase = await this.get_origin(caseId);
    if (!bcase) {
      return this.utils.service.fail("案例不存在");
    }

    const files = [];
    files.push(bcase.caseCoverImg);
    files.push(...bcase.caseMainImgs);

    await this.model.remove(bcase);

    await this.attService.remove(files);

    return this.utils.service.success(caseId);
  }

  async get_case(caseId: string) {
    const builder = this.model
      .createQueryBuilder("case")
      .leftJoinAndSelect("case.caseCoverImg", "caseCoverImg")
      .leftJoinAndSelect("case.caseMainImgs", "caseMainImgs")
      .where("case.caseId = :caseId", { caseId });

    const result = await builder.getOne();
    const data = new CaseDto(result);

    return this.utils.service.success(data);
  }

  async get_case_list() {
    const builder = this.model
      .createQueryBuilder("case")
      .leftJoinAndSelect("case.caseCoverImg", "caseCoverImg")
      .leftJoinAndSelect("case.caseMainImgs", "caseMainImgs")
      .orderBy("case.createAt", "DESC");

    const result = await builder.getMany();
    const list = result.map((d) => new CaseDto(d));
    return this.utils.service.success(list);
  }

  async get_case_page_list(dto: CasePageQueryDto) {
    const builder = this.model
      .createQueryBuilder("case")
      .leftJoinAndSelect("case.caseCoverImg", "caseCoverImg")
      .leftJoinAndSelect("case.caseMainImgs", "caseMainImgs")
      .where("1=1")
      .orderBy("case.createAt", "DESC");

    if (dto.caseMainTitle) {
      builder.andWhere("case.caseMainTitle like :caseMainTitle", {
        caseMainTitle: `%${dto.caseMainTitle}%`
      });
    }

    if (dto.caseSubTitle) {
      builder.andWhere("case.caseSubTitle like :caseSubTitle", {
        caseSubTitle: `%${dto.caseSubTitle}%`
      });
    }
    const total = await builder.getCount();

    builder.skip((dto.current - 1) * dto.pageSize);
    builder.take(dto.pageSize);

    const list = await builder.getMany();
    const records = list.map((d) => new CaseDto(d));

    return this.utils.service.success({
      total,
      records,
      current: Number(dto.current),
      pageSize: Number(dto.pageSize)
    });
  }
}
